define(["dojo/_base/declare",
	 "dijit/_WidgetBase", 
	 "dijit/_TemplatedMixin",
	 "dojo/_base/lang",
	 "dojo/_base/Deferred",
	 "dojo/dom-class"], function(declare, _WidgetBase, _TemplatedMixin, lang, Deferred, domClass) {

    return declare([_WidgetBase, _TemplatedMixin], (function () {
    	//
    	var protectAnimationDecorator, template, onMouseEnterAnimation, onMouseLeaveAnimation;
    	
    	protectAnimationDecorator = function (fn) {
			return function () {
				var that = this;
				if (this._inAnimationState)
					return;
                this._inAnimationState = true;
				fn.apply(this, arguments).then(function () {
					that._inAnimationState = false;
				}, function () {
					that._inAnimationState = false;
				});
			};
		};
		// widget HTML template
		template = 
       	 '<div class="b-twitter-message">' +
       	 	'<div class="b-twitter-message__text" data-dojo-attach-point="textNode">${!text}</div>' +
            '<div class="b-twitter-message__time" data-dojo-attach-point="timeNode"></div>' +
         '</div>';
		//
		onMouseEnterAnimation = function () {
			var d = new Deferred();
			domClass.add(this.domNode, "b-twitter-message_active");
			d.resolve();
			return d;
		};
		onMouseLeaveAnimation = function () {
			var d = new Deferred();
			domClass.remove(this.domNode, "b-twitter-message_active");
			d.resolve();
			return d;
		};
		// widget prototype
		return {
            templateString: template,
            constructor: function () {
                this._inAnimationState = false;
            },
            _setTimeAttr: function (t) {
            	if (t) {
            		this._set('time', t);
            		this.timeNode.innerHTML = t;
            	}
            },
            postCreate: function () {
                var domNode = this.domNode;
                this.inherited(arguments);
                this.connect(domNode, "onmouseenter", function(e) {
                    return this._focusIn(e);
                });
                this.connect(domNode, "onmouseleave", function(e) {
                    return this._focusOut(e);
                });
            },
            _focusIn: protectAnimationDecorator(onMouseEnterAnimation),
            _focusOut: protectAnimationDecorator(onMouseLeaveAnimation)
        };
	}()));    		        	
});